home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / haeberli / libgutil / colormod.c < prev    next >
C/C++ Source or Header  |  1994-08-01  |  7KB  |  393 lines

  1. /*
  2.  * Copyright 1991, 1992, 1993, 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. /*
  18.  *    colormod -
  19.  *            Define some transforms between different color models.
  20.  *
  21.  *
  22.  *           Henry Moreton and Paul Haeberli - 1984
  23.  *
  24.  *    exports
  25.  *
  26.     void irgb_to_rgb(ir,ig,ib,r,g,b)
  27.     void cmy_to_rgb(c,m,y,r,g,b)
  28.     void hls_to_rgb(h,l,s,r,g,b)
  29.     void hsv_to_rgb(h,s,v,r,g,b)
  30.     void hsb_to_rgb(h,s,v,r,g,b)
  31.     void yiq_to_rgb(y,i,q,r,g,b)
  32.  
  33.     void rgb_to_rgb(fr,fg,fb,tr,tg,tb)
  34.  
  35.     void rgb_to_cmy(r,g,b,c,m,y)
  36.     void rgb_to_irgb(r,g,b,ir,ig,ib)
  37.     void rgb_to_hls(r,g,b,h,l,s)
  38.     void rgb_to_hsv(r,g,b,lh,ls,lv)
  39.     void rgb_to_hsb(r,g,b,lh,ls,lv)
  40.     void rgb_to_yiq(r,g,b,y,i,q)
  41.  
  42.     void setcolorsys(sys)
  43.     int getcolorsys(sys)
  44.     void torgb(r,g,b,tr,tg,tb)
  45.     void fromrgb(r,g,b,tr,tg,tb)
  46.     void rgbcomplement(r,g,b,cr,cg,cb)
  47.  *
  48.  */
  49. #include "math.h"
  50. #include "stdio.h"
  51. #include "colormod.h"
  52.  
  53. void rgb_to_rgb();
  54.  
  55. static void (*tofunc)() = rgb_to_rgb;
  56. static void (*fromfunc)() = rgb_to_rgb;
  57. static int colorsys = COLORSYS_RGB;
  58.  
  59. #define MIN(a, b)       (((a) < (b)) ? (a) : (b))
  60. #define MAX(a, b)       (((a) > (b)) ? (a) : (b))
  61.  
  62. /*
  63.  *    Convert FROM various formats TO rgb.
  64.  *
  65.  *
  66.  */
  67. void irgb_to_rgb(ir,ig,ib,r,g,b)
  68. int ir, ig, ib;
  69. float *r, *g, *b;
  70. {
  71.     *r = ir/255.0;
  72.     *g = ig/255.0;
  73.     *b = ib/255.0;
  74. }
  75.  
  76. void cmy_to_rgb(c,m,y,r,g,b)
  77. float c, m, y;
  78. float *r, *g, *b;
  79. {
  80.     *r = 1.0-c;
  81.     *g = 1.0-m;
  82.     *b = 1.0-y;
  83. }
  84.  
  85. static float value(n1, n2, hue)
  86. float n1, n2, hue;
  87. {
  88.     if (hue>360)
  89.     hue-=360;
  90.     if (hue<0)
  91.     hue+=360;
  92.     if (hue<60)
  93.     return(n1+(n2-n1)*(hue/60.0));
  94.     if (hue<180)
  95.     return(n2);
  96.     if (hue<240)
  97.     return(n1+(n2-n1)*((240-hue)/60.0));
  98.     return n1;
  99. }
  100.  
  101. void hls_to_rgb(h,l,s,r,g,b)
  102. float h, l, s;
  103. float *r, *g, *b;
  104. {
  105.     float    m1, m2;
  106.  
  107.     h *= 360.0;
  108.     if (l<=0.5)
  109.     m2 = l*(1.0+s);
  110.     else
  111.     m2 = l+s-l*s;
  112.     m1 = 2*l-m2;
  113.     if (s==0)
  114.     *r = *g = *b = l;
  115.     else {
  116.     *r = value(m1,m2,h+120.0);
  117.     *g = value(m1,m2,h);
  118.     *b = value(m1,m2,h-120.0);
  119.     }
  120. }
  121.  
  122. void hsv_to_rgb(h,s,v,r,g,b)
  123. float h, s, v;
  124. float *r, *g, *b;
  125. {
  126.     int i;
  127.     float f, p, q, t;
  128.  
  129.     h *= 360.0;
  130.     if (s==0) {
  131.     *r = v;
  132.     *g = v;
  133.     *b = v;
  134.     } else {
  135.     if (h==360) 
  136.         h = 0;
  137.     h /= 60;
  138.     i = ffloor(h);
  139.     f = h - i;
  140.     p = v*(1.0-s);
  141.     q = v*(1.0-(s*f));
  142.     t = v*(1.0-(s*(1.0-f)));
  143.     switch (i) {
  144.         case 0 : 
  145.         *r = v;
  146.         *g = t;
  147.         *b = p;
  148.         break;
  149.         case 1 : 
  150.         *r = q;
  151.         *g = v;
  152.         *b = p;
  153.         break;
  154.         case 2 : 
  155.         *r = p;
  156.         *g = v;
  157.         *b = t;
  158.         break;
  159.         case 3 : 
  160.         *r = p;
  161.         *g = q;
  162.         *b = v;
  163.         break;
  164.         case 4 : 
  165.         *r = t;
  166.         *g = p;
  167.         *b = v;
  168.         break;
  169.         case 5 : 
  170.         *r = v;
  171.         *g = p;
  172.         *b = q;
  173.         break;
  174.     }
  175.     }
  176. }
  177.  
  178. void hsb_to_rgb(h,s,v,r,g,b)
  179. float h, s, v;
  180. float *r, *g, *b;
  181. {
  182.     hsv_to_rgb(h,s,v,r,g,b);
  183. }
  184.  
  185. void yiq_to_rgb(y,i,q,r,g,b)
  186. float y, i, q;
  187. float *r, *g, *b;
  188. {
  189.     *r = y + 0.948262*i + 0.624013*q;
  190.     *g = y + -0.276066*i + -0.63981*q;
  191.     *b = y + -1.10545*i + 1.72986*q;
  192. }
  193.  
  194. /*
  195.  *    Convert FROM rgb TO rgb.
  196.  *
  197.  *
  198.  */
  199. void rgb_to_rgb(fr,fg,fb,tr,tg,tb)
  200. float fr, fg, fb;
  201. float *tr, *tg, *tb;
  202. {
  203.     *tr = fr;
  204.     *tg = fg;
  205.     *tb = fb;
  206. }
  207.  
  208. /*
  209.  *    Convert TO various formats FROM rgb.
  210.  *
  211.  *
  212.  */
  213. void rgb_to_cmy(r,g,b,c,m,y)
  214. float r, g, b;
  215. float *c, *m, *y;
  216. {
  217.     *c = 1.0-r;
  218.     *m = 1.0-g;
  219.     *y = 1.0-b;
  220. }
  221.  
  222. void rgb_to_irgb(r,g,b,ir,ig,ib)
  223. float r, g, b;
  224. int *ir, *ig, *ib;
  225. {
  226.     *ir = (r*255.0)+0.5;
  227.     *ig = (g*255.0)+0.5;
  228.     *ib = (b*255.0)+0.5;
  229. }
  230.  
  231. void rgb_to_hls(r,g,b,h,l,s)
  232. float r, g, b;
  233. float *h, *l, *s;
  234. {
  235.     float rc, gc, bc;
  236.     float maxcol, mincol, cdelta;
  237.  
  238.     maxcol = MAX(r,MAX(g,b));
  239.     mincol = MIN(r,MIN(g,b));
  240.     *l = (mincol+maxcol)/2;        /* lightness */
  241.     if (maxcol==mincol) {        /* achromatic case */
  242.     *s = 0;        /* *h is undefined in the achromatic case */
  243.     *h = 0;
  244.     } else {
  245.     if (*l<=0.5)
  246.         *s = (maxcol-mincol)/(maxcol+mincol);
  247.     else
  248.         *s = (maxcol-mincol)/(2-maxcol-mincol);
  249. /* find hue */
  250.     cdelta = maxcol-mincol;
  251.     rc = (maxcol-r)/cdelta;
  252.     gc = (maxcol-g)/cdelta;
  253.     bc = (maxcol-b)/cdelta;
  254.     if (r==maxcol)
  255.         *h = bc-gc;
  256.     else if (g==maxcol)
  257.         *h = 2+rc-bc;
  258.     else 
  259.         *h = 4+gc-rc;
  260.     *h *= 60.0;
  261.     if (*h<0.0)
  262.         *h += 360.0;
  263.     *h /= 360.0;
  264.     }
  265. }
  266.  
  267. void rgb_to_hsv(r,g,b,lh,ls,lv)
  268. float r, g, b;
  269. float *lh, *ls, *lv;
  270. {
  271.     float h, s, v;
  272.     float cmax, cmin, cdelta;
  273.     float rc, gc, bc;
  274.  
  275.     /* find the cmax and cmin of r g b */
  276.     cmax = r; 
  277.     cmin = r;
  278.     cmax = (g>cmax ? g:cmax);
  279.     cmin = (g<cmin ? g:cmin);
  280.     cmax = (b>cmax ? b:cmax);
  281.     cmin = (b<cmin ? b:cmin);
  282.     v = cmax;        /* value */
  283.     if (cmax!=0.0)
  284.     s = (cmax - cmin)/cmax;
  285.     else {
  286.     s = 0.0;
  287.     h = 0.0;
  288.     }
  289.     if (s == 0.0)
  290.     h = -1.0;
  291.     else {
  292.     cdelta = cmax-cmin;
  293.     rc = (cmax-r)/cdelta;
  294.     gc = (cmax-g)/cdelta;
  295.     bc = (cmax-b)/cdelta;
  296.     if (r==cmax)
  297.         h = bc-gc;
  298.     else
  299.         if (g==cmax)
  300.         h = 2.0+rc-bc;
  301.         else
  302.         h = 4.0+gc-rc;
  303.     h = h*60.0;
  304.     if (h<0.0)
  305.         h += 360.0;
  306.     }
  307.     *ls = s;
  308.     *lh = h/360.0;
  309.     *lv = v;
  310. }
  311.  
  312. void rgb_to_hsb(r,g,b,lh,ls,lv)
  313. float r, g, b;
  314. float *lh, *ls, *lv;
  315. {
  316.     rgb_to_hsv(r,g,b,lh,ls,lv);
  317. }
  318.  
  319. void rgb_to_yiq(r,g,b,y,i,q)
  320. float    r, g, b;
  321. float    *y, *i, *q;
  322. {
  323.     *y = (0.30*r+0.59*g+0.11*b);
  324.     *i = (0.60 *r-0.28*g-0.32*b);
  325.     *q = (0.21*r-0.52*g+0.31*b);
  326. }
  327.  
  328. void setcolorsys(sys)
  329. {
  330.     switch(sys) {
  331.     case COLORSYS_RGB: 
  332.         tofunc = rgb_to_rgb;
  333.         fromfunc = rgb_to_rgb;
  334.         colorsys = sys;
  335.         break;
  336.     case COLORSYS_CMY: 
  337.         tofunc = cmy_to_rgb;
  338.         fromfunc = rgb_to_cmy;
  339.         colorsys = sys;
  340.         break;
  341.     case COLORSYS_HSV: 
  342.         tofunc = hsv_to_rgb;
  343.         fromfunc = rgb_to_hsv;
  344.         colorsys = sys;
  345.         break;
  346.     case COLORSYS_HLS: 
  347.         tofunc = hls_to_rgb;
  348.         fromfunc = rgb_to_hls;
  349.         colorsys = sys;
  350.         break;
  351.     case COLORSYS_YIQ: 
  352.         tofunc = yiq_to_rgb;
  353.         fromfunc = rgb_to_yiq;
  354.         colorsys = sys;
  355.         break;
  356.      default:  
  357.         fprintf(stderr,"bad color system no %d\n",sys);
  358.         break;
  359.     }
  360. }
  361.  
  362. int getcolorsys(sys)
  363. {
  364.     return colorsys;
  365. }
  366.  
  367. void torgb(r,g,b,tr,tg,tb)
  368. float r, g, b;
  369. float *tr, *tg, *tb;
  370. {
  371.     tofunc(r,g,b,tr,tg,tb);
  372. }
  373.  
  374. void fromrgb(r,g,b,tr,tg,tb)
  375. float r, g, b;
  376. float *tr, *tg, *tb;
  377. {
  378.     fromfunc(r,g,b,tr,tg,tb);
  379. }
  380.  
  381. void rgbcomplement(r,g,b,cr,cg,cb)
  382. float r, g, b;
  383. float *cr, *cg, *cb;
  384. {
  385.     float h, s, v;
  386.     
  387.     rgb_to_hsv(r,g,b,&h,&s,&v);
  388.     v = v+0.5;
  389.     if(v>1.0);
  390.     v -= 1.0;
  391.     hsv_to_rgb(h,s,v,cr,cg,cb);
  392. }
  393.